/**
 ******************************************************************************
 * @file	battery.c
 * @brief	libotdr-peripheral.so
 *
 * Copyright (C) 2017 桂林聚联科技有限公司, Inc. All Rights Reserved.
 *
 * @section Depend
 *	-# spi_mxs.ko
 *	-# spidev.ko
 *	-# libfpga-2016.so
 *
 * 2016-10-21,MenglongWu,MenglongWoo@aliyun.com
 */
#include <printl.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>

#include "otdr-peripheral.h"

#define OTDR_DBG_LEVEL 1
#ifdef NDEBUG
#define this_dbg(fmt, ...)
#else
#define this_dbg(fmt, ...) PRINTL(OTDR_DBG_LEVEL, C_DEBUG fmt C_NORMAL, ##__VA_ARGS__)
#endif

#define DEVICE_DEF_NAME "/dev/mxs-adc"
#define DEF_BAT1_CH     10
#define DEF_BAT2_CH     11

static char *device  = DEVICE_DEF_NAME;
static int   bat1_ch = DEF_BAT1_CH;
static int   bat2_ch = DEF_BAT2_CH;

#define DEF_PIN_POWER_ADAPTER "pin_power_adapter"
#define DEF_PIN_BAT1          "pin_bat1_status"
#define DEF_PIN_BAT2          "pin_bat2_status"
static char *dev_pin_adapter = DEF_PIN_POWER_ADAPTER;
static char *dev_pin_bat1    = DEF_PIN_BAT1;
static char *dev_pin_bat2    = DEF_PIN_BAT2;

int imx287_getBatteryPower(int *power1, int *power2);
static void __attribute__((constructor)) _load_env_battery()
{
    printf("%s %d\r\n", __FUNCTION__, __LINE__);
    sleep(1);
    char *env = NULL;
    env       = getenv("DEVICE_BATTERY");
    if (env) {
	device = env;
    }

    env = getenv("DEVICE_BATTERY1_CH");
    if (env) {
	bat1_ch = atoi(env) + 10;
    }
    env = getenv("DEVICE_BATTERY2_CH");
    if (env) {
	bat2_ch = atoi(env) + 10;
    }


    env = getenv("DEVICE_PIN_POWER_ADAPTER");
    if (env) {
	dev_pin_adapter = env;
    }
    env = getenv("DEVICE_PIN_BAT1_STATUS");
    if (env) {
	dev_pin_bat1 = env;
    }
    env = getenv("DEVICE_PIN_BAT2_STATUS");
    if (env) {
	dev_pin_bat2 = env;
    }

    // 读取第一次的垃圾数据
    int unuse;
    //	getBatteryPower(&unuse, &unuse);
}

/**
 * @brief	读取电池电量
 * @param	power1 第一块电池
 * @param	power2 第二块电池
 * @retval	null
 * @remarks
 * @see
 */

int imx287_getBatteryPower(int *power1, int *power2)
{
    // TODO must be > 6500 = 6.5V
    // printf("%s %d\r\n", __FUNCTION__, __LINE__);
    int   iRes;
    int   fd;
    int   tmp1 = 0, tmp2 = 0;
    float vol1, vol2;
    *power1 = 8000;
    *power2 = 8000;
    return 0;

#if 1  // ls2k
    *power1 = 0;
    *power2 = 0;
    return 0;
#endif
    fd = open(device, O_RDONLY);
    if (fd < 0) {
	printf("%s() %d:fail open device %s\n", __FUNCTION__, __LINE__, device);
	perror("");
	return -1;
    }
    for (int i = 0; i < 16; i++) {
	ioctl(fd, bat1_ch, &iRes);
	tmp1 += iRes;
	ioctl(fd, bat2_ch, &iRes);
	tmp2 += iRes;
    }
    tmp1 = tmp1 >> 4;
    tmp2 = tmp2 >> 4;
#define C (-0.32)
#define K (0.0022)
    vol1    = (float)tmp1 * K + C;
    vol2    = (float)tmp2 * K + C;
    *power1 = (vol1 > 0) ? (int)(vol1 * 1000) : 0;
    *power2 = (vol2 > 0) ? (int)(vol2 * 1000) : 0;

    close(fd);
    return 0;
}

int imx287_get_bat_vol(double *power1, double *power2)
{
    int iRes;
    int fd;
    int tmp1 = 0, tmp2 = 0;
    *power1 = 1;
    *power2 = 1;
    return 7;

    fd = open(device, O_RDONLY);
    if (fd < 0) {
	printf("%s() %d:fail open device %s\n", __FUNCTION__, __LINE__, device);
	perror("");
	return -1;
    }
    for (int i = 0; i < 16; i++) {
	ioctl(fd, bat1_ch, &iRes);
	tmp1 += iRes;
	ioctl(fd, bat2_ch, &iRes);
	tmp2 += iRes;
    }
    tmp1    = tmp1 >> 4;
    tmp2    = tmp2 >> 4;
    *power1 = (tmp1 * 1.85) / 4096.0;
    *power2 = (tmp2 * 1.85) / 4096.0;

    close(fd);
    return 0;
}


/**
 * @brief	获取充电状态
 * @param chargeState1，电池1的充电状态， 值为1正在充电，值为0没有充电。
 * @param chargeState2，电池2的充电状态， 值为1正在充电，值为0没有充电。
 * @param externalPowerSupply，外部电源状态， 值为1接了外部电源，值为0没有外部电源。
 * @retval	返回值：0成功，-1失败。
 * @remarks
 * @see
 */

int imx287_getChargeState(
	int *chargeState1,
	int *chargeState2,
	int *externalPowerSupply)
{
    // printf("%s %d\r\n", __FUNCTION__, __LINE__);
    *chargeState1        = 0;
    *chargeState2        = 0;
    *externalPowerSupply = 1;


    assert(chargeState1 != NULL);
    assert(chargeState2 != NULL);
    assert(externalPowerSupply != NULL);
    FILE *fp;
    char  strout[4];
    char  strcmd[64];
    int   ret;

#if 0
	snprintf(strcmd, sizeof(strcmd),
	         "cat /sys/class/gpio/%s/value", dev_pin_adapter);
	fp = popen(strcmd, "r");
	if (fp == NULL) {
		return -1;
	}
	ret = fread( strout, sizeof(char), sizeof(strout) - 1, fp);
	strout[ret] = '\0';
	*externalPowerSupply = atoi(strout);
	pclose(fp);
#endif
    snprintf(strcmd, sizeof(strcmd), "/sys/class/gpio/%s/value", dev_pin_adapter);
    fp = fopen(strcmd, "r");
    if (fp == NULL) {
	printf("%s() %d:fail open file %s\n", __FUNCTION__, __LINE__, strcmd);
	perror("");
	return -1;
    }
    ret                  = fread(strout, sizeof(char), 1, fp);
    strout[ret]          = '\0';
    *externalPowerSupply = atoi(strout);

    fclose(fp);

    snprintf(strcmd, sizeof(strcmd), "/sys/class/gpio/%s/value", dev_pin_bat1);
    fp = fopen(strcmd, "r");
    if (fp == NULL) {
	printf("%s() %d:fail open file %s\n", __FUNCTION__, __LINE__, strcmd);
	perror("");
	return -1;
    }
    ret           = fread(strout, sizeof(char), 1, fp);
    strout[ret]   = '\0';
    *chargeState1 = atoi(strout);
    fclose(fp);
    snprintf(strcmd, sizeof(strcmd), "/sys/class/gpio/%s/value", dev_pin_bat2);
    fp = fopen(strcmd, "r");
    if (fp == NULL) {
	printf("%s() %d:fail open file %s\n", __FUNCTION__, __LINE__, strcmd);
	perror("");
	return -1;
    }
    ret           = fread(strout, sizeof(char), 1, fp);
    strout[ret]   = '\0';
    *chargeState2 = atoi(strout);
    fclose(fp);

    return 0;
}
